﻿using KWT.DRG_DIP.API.Infrastructure;
using KWT.DRG_DIP.Common;
using KWT.DRG_DIP.DB;
using KWT.DRG_DIP.DO.qcRules;
using KWT.DRG_DIP.DO.System;
using KWT.DRG_DIP.DTO.qcRules;
using KWT.DRG_DIP.ISvc;
using KWT.DRG_DIP.PO.QC;
using KWT.DRG_DIP.PO.qcRules;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using RulesEngine.Models;
using System.Collections.Generic;

namespace KWT.DRG_DIP.API.Controllers.qcRules
{
    /// <summary>
    /// 质控规则
    /// </summary>
    [ApiExplorerSettings(GroupName = "qc")]
    [AllowAnonymous]
    public class RulesController : QCControllerBase
    {
        /// <summary>
        /// 
        /// </summary>
        public IUserRulesEngineSvc userRulesEngine { get; set; }

        #region 添加或编辑
        /// <summary>
        /// 添加或编辑
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        public OutputResult AddOrUpdate(InQcRules dto)
        {
            string? tenantID = HttpContext.Request.Headers["TenantID"];
            if (string.IsNullOrEmpty(tenantID))
            {
                return Fail("缺少租户ID");
            }

            #region 数据校验
            if (string.IsNullOrEmpty(dto.ruleName))
            {
                return Fail("规则名称不可为空");
            }

            if (string.IsNullOrEmpty(dto.ruleExpressionIn))
            {
                return Fail("规则表达式不可为空");
            }
            #endregion

            #region 表达式验证，转换
            string Expression = "";
            string ruleJson = "";
            try
            {
                Rule rule = userRulesEngine.TransformExpression(tenantID, dto.QRID, dto.ruleName, dto.ruleExpressionIn, dto.ruleResult);
                Expression = rule.Expression;
                ruleJson = JsonConvert.SerializeObject(rule);
            }
            catch (Exception ex)
            {
                return Fail(ex.Message);
            }

            #endregion

            #region 编辑或保存
            var qcRules = _mapper.Map<qc_Rules>(dto);

            if (!ef.Set<qc_Rules>().Any(x => x.QRID == dto.QRID))
            {
                if (ef.Set<qc_Rules>().Any(x => x.ruleName == dto.ruleName))
                {
                    return Fail("规则名称不可重复！");
                }

                qcRules.QRID = "QR" + snow_id.CreateId().ToString();
                qcRules.ruleExpression = Expression;
                qcRules.ruleJson = ruleJson;

                dto.QRID = qcRules.QRID;
                ef.Add(qcRules);
            }
            else
            {
                if (ef.Set<qc_Rules>().Any(x => x.ruleName == dto.ruleName && x.QRID != dto.QRID))
                {
                    return Fail("规则名称不可重复！");
                }

                var para = ef.Find<qc_Rules>(dto.QRID);
                if (para == null)
                {
                    return Fail("该项不存在！");
                }
                para.ruleCategory = dto.ruleCategory;
                para.ruleName = dto.ruleName;
                para.ruleDes = dto.ruleDes;
                para.problemCategory = dto.problemCategory;
                para.ruleLevel = dto.ruleLevel;
                para.ruleProperties = dto.ruleProperties;
                para.ruleExpressionIn = dto.ruleExpressionIn;
                para.ruleResult = dto.ruleResult;
                para.ruleExpression = Expression;
                para.ruleJson = ruleJson;
                ef.Update(para);
            }
            var flag = ef.SaveChanges() > 0;
            return Output(true, "操作成功", "操作失败");
            #endregion
        }
        #endregion

        #region 批量删除
        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="qrIDs"></param>
        /// <returns></returns>
        [HttpGet]
        public OutputResult Del([FromQuery] string[] qrIDs)
        {
            var flag = ef.Set<qc_Rules>().Where(x => qrIDs.Contains(x.QRID)).ExecuteDelete() > 0;
            return Output(flag, "操作成功", "操作失败");

        }
        #endregion

        #region  分页查询
        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [ProducesResponseType(typeof(Output<qc_Rules>), 200)]
        [HttpPost]
        public OutputResult PageList(InQcRulesPage dto)
        {
            #region 查询条件
            var q = ef.Set<qc_Rules>().AsQueryable();
            if (!string.IsNullOrEmpty(dto.ruleName))
            {
                //规则名称
                q = q.Where(x => EF.Functions.Like(x.ruleName, $"%{dto.ruleName}%"));
            }
            if (!string.IsNullOrEmpty(dto.ruleCategory))
            {
                //规则分类
                q = q.Where(x => EF.Functions.Like(x.ruleCategory, $"%{dto.ruleCategory}%"));
            }
            if (!string.IsNullOrEmpty(dto.problemCategory))
            {
                //问题分类
                q = q.Where(x => EF.Functions.Like(x.problemCategory, $"%{dto.problemCategory}%"));
            }
            if (!string.IsNullOrEmpty(dto.ruleLevel))
            {
                //规则级别
                q = q.Where(x => x.ruleLevel == dto.ruleLevel);
            }
            if (!string.IsNullOrEmpty(dto.ruleProperties))
            {
                //规则属性
                q = q.Where(x => x.ruleProperties == dto.ruleProperties);
            }
            if (dto.isEnable != -1)
            {
                //是否启用
                q = q.Where(x => x.isEnable == dto.isEnable);
            }
            #endregion

            int total = q.Count();
            var list = q.ToPageList(dto.PageNo, dto.PageSize);
            return Output(true, "", "", new PageList<qc_Rules>() { List = list, Total = total });
        }
        #endregion

        #region 根据ID获得规则
        /// <summary>
        /// 根据ID获得规则
        /// </summary>
        /// <param name="vrID">值域ID</param>
        /// <returns></returns>
        [ProducesResponseType(typeof(Output<qc_Rules>), 200)]
        [HttpGet]
        public OutputResult GetRuleByID([FromQuery] string qrID)
        {
            var rule = ef.Set<qc_Rules>().FirstOrDefault(x => x.QRID == qrID);
            return Output(true, "操作成功", "操作失败", rule);

        }
        #endregion

        #region 设置启用状态
        /// <summary>
        /// 设置启用状态
        /// </summary>
        /// <param name="qrIDs"></param>
        /// <returns></returns>
        [HttpPost]
        public OutputResult SetEnable(InQcRulesEnable dto)
        {
            var rules = ef.Set<qc_Rules>().Where(x => dto.QRIDs.Contains(x.QRID)).ToList();
            rules.ForEach(x => x.isEnable = dto.isEnable);
            ef.Set<qc_Rules>().UpdateRange(rules);
            ef.SaveChanges();
            return Output(true, "操作成功", "操作失败");
        }
        #endregion

        #region 执行规则
        /// <summary>
        /// 执行规则
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [ProducesResponseType(typeof(Output<OutRulesResult>), 200)]
        [HttpPost]
        public OutputResult ExecRules(ruleInput input)
        {
            string? tenantID = HttpContext.Request.Headers["TenantID"];
            if (string.IsNullOrEmpty(tenantID))
            {
                return Fail("缺少租户ID");
            }

            var LstOutRules = userRulesEngine.ExecRules(tenantID, input);
            return Output(true, "", "", LstOutRules);
        }
        #endregion
    }
}
